<?php
/**
 * User: Titan
 * Date: Oct 13, 2010
 * Time: 3:37:34 PM
 */

/**
 * system_redirect()
 * 
 * This function redirects a user to a different location. 
 * 
 * This is useful for form validation and direction, 404 errors, etc.
 * 
 * @param mixed $url
 * @param integer $http_code
 * @return void
 */
function system_redirect($url, $http_code = 302)
{
	header('Location: ' . $url, TRUE, $http_code);
	exit;
}

/**
 * system_add_styles()
 * 
 * A global function to add a stylesheet to the html
 * 
 * @param $path
 *      (optional) the path of the stylesheet
 * 
 * @return
 *      an array of the stylesheets
 */
function system_add_styles($path = null)
{
	static $styles = array();

	if (isset($path))
	{
		$styles[] = $path;
	}

	return $styles;
}

/**
 * system_get_styles()
 * 
 * This function returns the <link> elements that are represented in array form either by the $styles parameter
 * or returned from the system_add_styles() function
 * 
 * @param mixed $styles
 * @return
 */
function system_get_styles($styles = null)
{
	global $base_path;
	$output = '';
	if (!isset($styles))
	{
		$styles = system_add_styles();
	}

	foreach ($styles as $file)
	{
		$output .= '<link type="text/css" rel="stylesheet" href="' . $base_path . $file . '" />' . "\n";
	}

	return $output;
}

/**
 * system_add_js()
 * 
 * A global function to add a script to the html
 * 
 * @param $script
 *      the path to the script or the inline script
 * 
 * @param $type
 *      'header' or 'footer'
 * 
 * @return
 *      an array() of the scripts
 */
function system_add_js($script = null, $type = 'default')
{
	static $javascript = array();

	if (isset($script))
	{
		switch ($type)
		{
			case 'default':
				$javascript[$type][] = $script;
				break;
			case 'inline':
				$javascript[$type][] = $script;
				break;
			default:
				break;
		}
	}

	return $javascript;
}

/**
 * system_get_js()
 *
 * This function outputs the <script> tags that are either inputs or returned by system_add_js()
 *  
 * @param mixed $scripts
 * @return void
 */
function system_get_js($scripts = null)
{
	global $base_path;

	$output = '';
	if (!isset($scripts))
	{
		$scripts = system_add_js();
	}

	$inline_prefix = "\n<!--//--><![CDATA[//><!--\n";
	$inline_suffix = "\n//--><!]]>\n";

	foreach ($scripts as $type => $data)
	{
		foreach ($data as $script)
		{
			switch ($type)
			{
				case 'default':
					$output .= '<script type="text/javascript" src="' . $base_path . $script . '"></script>';
					break;
				case 'inline':
					$output .= '<script type="text/javascript">' . $inline_prefix . $script . $inline_suffix . '</script>' . "\n";
					break;
				default:
					break;
			}
		}
	}

	return $output;
}

/**
 * system_get_html_head()
 * 
 * @param mixed $data
 * @return
 */
function system_get_html_head($data = null)
{
	return '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' . "\n";
}

/**
 * html_safe()
 * 
 * Filters text to make sure that it is safe to include in HTML
 * 
 * @param mixed $text
 * @return
 */
function html_safe($text)
{
	return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}

/**
 * krumo_ob()
 * 
 * This function is useful for debugging (ie. displaying variables to the page, etc.)
 * 
 * This function will only work if DEBUG is defined as TRUE in the main index.php file
 * 
 * @param mixed $object
 * @return
 */
function krumo_ob($object)
{
	ob_start();
	krumo($object);
	$output = ob_get_contents();
	ob_end_clean();
	return $output;
}

/**
 * debug()
 * 
 * This function formats and prints an object/string/array in "pretty" way to the system messages area
 * 
 * @param mixed $object
 * @return void
 */
function debug($object)
{
	if (defined('DEBUG') && DEBUG === TRUE)
	{
		$output = krumo_ob($object);

		system_set_message($output);
		return;
	}

	ob_start();
	var_dump($object);
	//print ('<br /><strong>Called from <em>' . xdebug_call_file() . ':' . xdebug_call_function() . ' line ' . xdebug_call_line() . '</em></strong>');
	print ('<br />----------------------------------------------------------------------------<br />');
	$output = ob_get_contents();
	ob_end_clean();
	system_set_message('<pre>' . $output . '</pre>');
}

/**
 * system_element_children()
 * 
 * This function returns any children elements from any array that do not have keys in the array
 * that begin with a # sign because those elements will be configuration variables for the represented object
 * 
 * @param mixed $elements
 * @return
 */
function system_element_children($elements)
{
	switch ($elements['#type'])
	{
		case 'form':
			return $elements['#inputs'];
			break;
		default:
			return array_filter(array_keys((array )$elements), 'attribute_filter');
			break;
	}
}

/**
 * attribute_filter()
 * 
 * Helper function for determining if array obj is a #attribute or an element
 * 
 * @param mixed $attr
 * @return
 */
function attribute_filter($attr)
{
	return !isset($attr[0]) || $attr[0] != '#';
}

/**
 * valid_email()
 * 
 * Validates email addresses
 * 
 * @param mixed $email
 * 		email address
 * 
 * @return
 * 		TRUE if is valid, FALSE if not
 */
function valid_email($email)
{
	return preg_match("/^\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b$/", $email);
}

/**
 * valid_url()
 * 
 * checks to see if a URL is valid. This function allows URLs of the form:
 * 
 * http://www.google.com
 * google.com
 * /index.php
 * 
 * @param mixed $url
 * 		the URL
 * 
 * @return
 * 		returns the URL if valid, else FALSE
 */
function valid_url($url)
{
	if (!preg_match("/^(((ht|f)tps?:\/\/)|(www.))[a-zA-Z0-9_\-.:#\/~?]+$/", $url))
	{
		if (!preg_match("/^([a-zA-Z0-9_%-]*\.[a-z]{2,4})(\.[a-z]{2})?((\/[a-zA-Z0-9_%-]*)+)?(\.[a-z]*)?/", $url))
		{
			if (!preg_match("/^((\/[a-zA-Z0-9_%-]*)+)(\.[a-z]*)?/", $url))
			{
				return base_path() . $url;
			}
		}
	}
	
	return $url;
}

/**
 * base_path()
 * 
 * Returns the base path for the site.
 * This is useful for rendering links so that a page doesn't have to "know where it is"
 * 
 * ie. a link doesn't have to be represented as ../../assets/images/logo.png
 * 
 * @return
 */
function base_path()
{
	return $GLOBALS['base_path'];
}

/**
 * site_name()
 * 
 * The name of the site
 * 
 * @return
 */
function site_name()
{
	return 'BugZapp';
}

/**
 * system_page_title()
 * 
 * sets and gets the title of the current page 
 * 
 * @param mixed $title
 * @return
 */
function system_page_title($title = null)
{
	static $page_title = '';

	if (isset($title))
	{
		$page_title = $title;
	}

	return $page_title;
}

/**
 * site_logo()
 * 
 * returns the <img> tag for the site logo
 * 
 * @return
 */
function site_logo()
{
	return '<img alt="' . site_name() . ' Logo" src="' . base_path() . 'assets/images/logo.png" />';
}

/**
 * system_breadcrumbs()
 * 
 * sets and gets any breadcrumbs defined by the current page
 * 
 * @param mixed $crumbs
 * @return
 */
function system_breadcrumbs($crumbs = null)
{
	static $breadcrumbs = array();

	if (isset($crumbs))
	{
		$breadcrumbs = array();
		foreach ($crumbs as $crumb)
		{
			if (is_array($crumb))
			{
				$breadcrumbs[] = a($crumb);
			}
			else
			{
				$breadcrumbs[] = $crumb;
			}
		}
	}

	return $breadcrumbs;
}

/**
 * a()
 * 
 * give a $link array, this function outputs a proper <a> tag
 * 
 * @param mixed $link
 * @return
 */
function a($link)
{
	$url = '';
	if (!empty($link['#href']))
	{
		$url = valid_url($link['#href']);
	}

	return '<a ' . (!empty($url) ? 'href="' . html_safe($url) . '" ' : '') . 'title="' . (empty($link['#title']) ? '' : html_safe($link['#title'])) . '"' . (empty($link['#attributes']) ? '' : render_attributes($link['#attributes'])) . '>' . html_safe($link['#anchor']) . '</a>' . "\n";
}

/***** System Prerender Functions *****/

/**
 * system_prerender_page()
 * 
 * Defines a bunch of useful variables for the output of the page, which are available in
 * the file page.tpl.php
 * 
 * @param mixed $vars
 * @return void
 */
function system_prerender_page(&$vars)
{
	$vars['head_title'] = system_page_title() . ' | ' . site_name();
	$vars['head'] = system_get_html_head();
	$vars['styles'] = system_get_styles();
	$vars['scripts'] = system_get_js();
	$vars['site_logo'] = site_logo();
	$vars['menu'] = render_menu(path_menu_links());
	$vars['breadcrumb'] = system_breadcrumbs();
	$vars['title'] = system_page_title();
	$vars['messages'] = render('system_messages', system_set_message());
	$vars['content'] = '';
}

/**
 * system_prerender_cleanup_page()
 * 
 * If any loaded pages changed the page title, output messages, and more, this function 
 * makes sure that those additions and changes are displayed on the page
 * 
 * @param mixed $vars
 * @return void
 */
function system_prerender_cleanup_page(&$vars)
{
	$vars['title'] = system_page_title();
	$vars['head_title'] = system_page_title() . ' | ' . site_name();
	$vars['messages'] = render('system_messages', system_set_message());
	$vars['breadcrumb'] = render('breadcrumbs', $vars['breadcrumb']);
}
